﻿"""
sample to show global,nonlocal and local name

Local vars are all names assigned IN ANY WAY inside a fuction. local vars are in function namespace.
Gloabl vars are in module namespace.

module会引入自己的scope，module scope中的名字称作global name. 位于所有function之外的name既是global。
function也会引入自己的scope。function scope中的名字称作local name, means local to fuction. function中name默认位于function自己的scope中.
嵌套的function，外层function scope对于内层function scope称作nolocal.

对function的每次调用都会创建自己的local scope. 理解这个对于recursive调用很重要.

name resolution的LEGB rule: local, enclosing function, global, built-in


"""


v =  'globalVar'  #global

def outer():
    v = 'outerVar'   #local
    def inner1():
        # outer.i is nonlocal, module.i is gloabl
        v = 'inner1Var'   #local. 
        print("local v={}".format(v))
    def inner2():
        nonlocal v
        print("nonlocal v={}".format(v))
    def inner3():
        global v
        print("global v={}".format(v))
    def inner4():
        v='inner4Var'
        if(True):
            v = 'inner4Var2'
            w = 'W1'
        if(True):
            print('local w={}'.format(w))
        print('local v={}'.format(v))
        
    def inner5():
        v = 'inner5Var'
        #global v            #error here, duplicate decl v
        print('v={}'.format(v))

    inner1()
    inner2()
    inner3()
    inner4()
    inner5()

def outer2():
    #nonlocal v         #error here. outer2 is a top-level fuction
    print("outer2 v={}".format(v))

if __name__=='__main__':
    outer()
